import copy


def Run_FCFS(track_request, TRACK_START, TRACK_MAX_COUNT, SCAN_DIRECTION):
    queue_FCFS = track_request.copy()
    queue_FCFS.insert(0, TRACK_START)
    return queue_FCFS


def findNearest(current, track_request, visited, TRACK_MAX_COUNT):
    minDis = TRACK_MAX_COUNT
    minIndex = -1
    for i in range(len(track_request)):
        if visited[i] == False:
            dis = abs(current - track_request[i])
            if dis < minDis:
                minDis = dis
                minIndex = i
    visited[minIndex] = True
    return minIndex, minDis


def Run_SSTF(track_request, TRACK_START, TRACK_MAX_COUNT, SCAN_DIRECTION):
    visited = [False] * len(track_request)
    queue_FCFS = []
    current = TRACK_START  # 起始的磁道
    for i in range(len(track_request) + 1):
        index, dis = findNearest(current, track_request, visited, TRACK_MAX_COUNT)
        queue_FCFS.append(current)
        current = track_request[index]
    return queue_FCFS


def Run_SCAN(track_request, TRACK_START, TRACK_MAX_COUNT, SCAN_DIRECTION):
    queue_SCAN = []
    queue_SCAN.append(TRACK_START)
    track_request_copy = copy.deepcopy(track_request)
    track_request_copy.sort()
    while track_request_copy.__len__() != 0:
        if SCAN_DIRECTION == 1:
            for track in track_request_copy.copy():
                if TRACK_START <= track:
                    queue_SCAN.append(track)
                    track_request_copy.remove(track)
            SCAN_DIRECTION = 0

        if SCAN_DIRECTION == 0:
            track_request_copy.reverse()
            for track in track_request_copy.copy():
                if TRACK_START >= track:
                    queue_SCAN.append(track)
                    track_request_copy.remove(track)
            SCAN_DIRECTION = 1
    return queue_SCAN


def Run_CSCAN(track_request, TRACK_START, TRACK_MAX_COUNT, SCAN_DIRECTION):
    queue_CSCAN = []
    queue_CSCAN.append(TRACK_START)
    track_request_copy = copy.deepcopy(track_request)
    track_request_copy.sort()
    i = 0
    is_find = False

    if SCAN_DIRECTION == 1:
        while i < track_request_copy.__len__():
            if (TRACK_START <= track_request_copy[i]) & (is_find == False):
                index = i
                i = 0
                is_find = True
            if is_find == True:
                queue_CSCAN.append(track_request_copy[index % len(track_request)])
                index += 1
            i += 1

    if SCAN_DIRECTION == 0:
        track_request_copy.reverse()
        while i < track_request_copy.__len__():
            if (TRACK_START >= track_request_copy[i]) & (is_find == False):
                index = i
                i = 0
                is_find = True
            if is_find == True:
                queue_CSCAN.append(track_request_copy[index % len(track_request)])
                index += 1
                current = track_request_copy[index % len(track_request)]
            i += 1

    return queue_CSCAN


def Run_Caculate(queue):
    sum_gap = sum([(abs(queue[i] - queue[i - 1])) for i in range(1, len(queue))])
    return sum_gap / len(queue)
